/*
 * Copyright (c) 2008, Xiong Yingfei, the University of Tokyo
 * All rights reserved.
 */
package ac.jp.u_tokyo.SyncLib.graphCombinator;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import ac.jp.u_tokyo.SyncLib.Mod;
import ac.jp.u_tokyo.SyncLib.NullMod;
import ac.jp.u_tokyo.SyncLib.Sync;


public class SyncHolder implements Iterable<Variable>, Comparable{
    
    private Variable[] _connectedVars;
    private Sync _sync;
    private int _priority;
    private int _index;

    public int getIndex()
	{
		return _index;
	}

	public void setIndex(int index)
	{
		_index = index;
	}
	
	/**
	 * 
	 * @param heldSync
	 * @param priority The larger, the higher the priority
	 */

	public SyncHolder(Sync heldSync, int priority) {
        super();
        _sync = heldSync;
        _connectedVars = new Variable[getVariableCount()];
        _priority = priority;
    }

    public int getVariableCount()
    {
        return _sync.getParaCount();
    }
    
    public void connectVariable(int index, Variable v) {
        assert(index >= 0 && index < getVariableCount());
        assert v != null;
        _connectedVars[index] = v;
        v.onConnectedToSyncHolder(this, index);
    }
    
    public Variable getVariable(int index) {
        return _connectedVars[index];
    }

    public Sync getSync() {
        return _sync;
    }

    public Iterator<Variable> iterator() {
        return Arrays.asList(_connectedVars).iterator();
    }

    Mod[] getModListFromVars() {
		Mod[] result = new Mod[getVariableCount()];
		for (int i = 0; i < getVariableCount(); i++)
		{
			result[i] = _connectedVars[i].getMod();
			assert result[i] != null;
		}
		return result;

    }
    
    Mod[] getHighModListFromVars() {
		Mod[] result = new Mod[getVariableCount()];
		for (int i = 0; i < getVariableCount(); i++)
		{
			result[i] = _connectedVars[i].getHighMod();
		}
		return result;

    }


    Object[] getValueListFromVars() {
		Object[] result = new Object[getVariableCount()];
		for (int i = 0; i < getVariableCount(); i++)
		{
			result[i] = _connectedVars[i].getValue();
		}
		return result;

    }

	public int getPriority()
	{
		return _priority;
	}
	
	public boolean hasModifiedVar() {
		for (Variable v : _connectedVars) {
			if (v.getMod() instanceof NullMod == false) return true;
		}
		return false;
	}

	public int compareTo(Object o)
	{
		SyncHolder rhs = (SyncHolder) o;
//		boolean lhsModifed = hasModifiedVar();
//		boolean rhsModifed = rhs.hasModifiedVar();
//		if (lhsModifed && !rhsModifed) return 1;
//		if (!lhsModifed && rhsModifed) return -1;
		if (this._priority > rhs._priority) return 1;
		else if (this._priority == rhs._priority) return 0;
		else return -1;
	}

}
